import { ChargeRecord } from '@common/database/entity/charge_record.entity';
import { ChatRoomEntity } from '@common/database/entity/chat_room.entity';
import { ChatRoundEntity } from '@common/database/entity/chat_round.entity';
import { User } from '@common/database/entity/user.entity';
import { RedisService } from '@common/reids/redis.service';
import { defaultConfig } from '@game/config/config';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Repository } from 'typeorm';

@Injectable()
export class RoomService {
  constructor(
    public readonly redisService: RedisService,

    @Inject('CHAT_ROOM_GREPOSITORY')
    public readonly repoRoom: Repository<ChatRoomEntity>,
    @Inject('CHAT_ROUND_GREPOSITORY')
    public readonly repoChatRoundEntity: Repository<ChatRoundEntity>,
  ) {}

  private logger: Logger = new Logger('RoomService');

  async getUsersInRoomByAdmin({}) {}

  async getUsersInRoom({ roomId }) {
    // 设置缓存.
    // let users: any = await this.redisService.hget('roomUsers' + roomId);
    let users: any = null;
    if (!users) {
      users = await this.repoRoom
        .createQueryBuilder('r')
        .where('r.roomId =:roomId', { roomId: roomId })
        .andWhere('r.type =:type', { type: 0 })
        .orderBy('r.sort', 'DESC')
        .addOrderBy('r.createdAt', 'DESC')
        .leftJoinAndSelect(ChargeRecord, 'd', 'r.userId = d.userId')
        .leftJoinAndSelect(User, 'c', 'r.userId = c.id')
        .select([
          'r.*',
          'c.nickName as nickName',
          'c.amount as amount',
          'c.weixin_openId as weixin_openId',
          'd.startTime as startTime',
          'd.endTime as endTime',
          'd.role as vipRole',
        ])
        .getRawMany();
      await this.redisService.hset({
        key: 'roomUsers' + roomId,
        value: users,
        expire: defaultConfig.roomCacheTime,
      });
    } else {
    }
    console.log(
      'getUsersInRoom',
      users.map((item) => item.userId),
    );
    // console.log(
    //   'getUsersInRoom',
    //   users
    // );

    await this.roomUsersListData({ users, roomId });
    const res = await this.roomUsersMapData({ users, roomId });
    // this.logger.log('getUsersInRoom room_req:', users.length, res);
    return users;
  }
  async setUsersInRoom(users,roomId) {
    // 设置缓存.
    // let users: any = await this.redisService.hget('roomUsers' + roomId);
    await this.redisService.hset({
      key: 'roomUsers' + roomId,
      value: users,
      expire: defaultConfig.roomCacheTime,
    });

    await this.roomUsersListData({ users, roomId });
    const res = await this.roomUsersMapData({ users, roomId });
    // this.logger.log('getUsersInRoom room_req:', users.length, res);
    return users;
  }
  async roomUsersListData({ users, roomId }) {
    this.redisService.hset({
      key: 'members_' + roomId,
      value: [...users],
      expire: defaultConfig.roomCacheTime,
    });

    return true;
  }
  async roomUsersMapData({ users, roomId, userId = -1, status = 1 }) {
    // 转换成key-val  {userId:XXX}
    let uk = {};
    // 1为在房间
    if (users && users.length > 0) {
      users.map((us) => {
        if (us.userId == userId) {
          uk = { ...uk, [us.userId]: status };
        } else {
          uk = { ...uk, [us.userId]: us.type == 0 ? 1 : 0 };
        }
      });
      // this.logger.warn('room_roomUsersMapData  ' + roomId, uk);

      this.redisService.hset({
        key: 'room_' + roomId,
        value: uk,
        // 房间数据开始自己维护，那么这里是获取redis数据的来源
        expire: defaultConfig.roomCacheTime,
      });
    } else {
      // this.logger.warn('room_roomUsersMapData  ' + roomId, uk);

      this.redisService.hset({
        key: 'room_' + roomId,
        value: {},
        // 房间数据开始自己维护，那么这里是获取redis数据的来源
        expire: defaultConfig.roomCacheTime,
      });
    }

    return uk;
  }

  async newUser({ userId, roomId }) {
    //       .where({ "r.roomId": roomId, "r.userId": userId })
    const users = await this.repoRoom
      .createQueryBuilder('r')
      .leftJoinAndSelect(User, 'c', 'c.id = r.userId')
      .leftJoinAndSelect(ChargeRecord, 'd', 'd.userId = r.userId')
      .where('r.roomId =:roomId', { roomId: roomId })
      .andWhere('r.userId =:userId', { userId: userId })
      .orderBy('r.sort', 'DESC')
      .addOrderBy('r.createdAt', 'DESC')
      .select([
        'r.*',
        'c.nickName',
        'c.weixin_openId',
        'd.startTime',
        'd.endTime',
        'd.role as vipRole',
      ])
      .getRawMany();
    return users;
  }

  async joinRoom(data) {
    // 查已经有的

    const usersList: any = await this.redisService.hget(
      'members_' + data.roomId,
    );
    const usersMap = await this.redisService.hget('room_' + data.roomId);

    if (usersList && usersList.length > 0) {
      //判断用户是否已经在缓存了

      this.logger.warn('room_' + data.roomId, usersMap, usersList.length);

      // 由于走缓存了 所以要做去重加入
      if (usersMap[data.userId] == 0 || usersMap[data.userId] == 1) {
        const res = await this.roomUsersMapData({
          users: usersList,
          roomId: data.roomId,
          userId: data.userId,
          status: 1,
        });

        this.logger.warn('room_done!!!' + data.roomId, res);
      } else {
        //
        // 构造一个新的
        const user = await this.newUser({
          userId: data.userId,
          roomId: data.roomId,
        });
        if (user) {
          usersList.push(user);

          //每次加入 都会把所有人设置为1有点问题哈
          await this.roomUsersListData({
            users: usersList,
            roomId: data.roomId,
          });

          const res2 = await this.roomUsersMapData({
            users: usersList,
            roomId: data.roomId,
            userId: data.userId,
            status: 1,
          });
          this.logger.warn('room_new' + data.roomId, res2);
        }
      }

      this.logger.error('roomuser_', data.userId);

      let roomuser: any = await this.redisService.hget(
        'roomuser_' + data.userId,
      );
      if (!roomuser) {
        // 1为房间还在
        roomuser = { [data.roomId]: 1 };
      } else {
        roomuser = { ...roomuser, [data.roomId]: 1 };
      }
      //加入房间成功后  还得建立一个 user：rooms的关系
      this.redisService.hset({
        key: 'roomuser_' + data.userId,
        value: roomuser,
        // 房间数据开始自己维护，那么这里是获取redis数据的来源
        expire: defaultConfig.roomCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
      });
      return usersList;
    }

    return null;
  }

  async leave(data) {
    //  其实就是更新 三组缓存
    let users = await this.getUsersInRoom({
      roomId: data.roomId,
    });
    users = users.filter((item) => item.userId != data.userId);
    await this.roomUsersListData({
      users,
      roomId: data.roomId,
    });

    const res2 = await this.roomUsersMapData({
      users,
      roomId: data.roomId,
    });
    this.logger.debug(' room_leave:', res2);

    return users;
  }
  /***
   * 检查在线情况 直接redis里判断标记位就行了
   */
  async onLineUserByRoom({ users }) {
    const memebers = await this.memebers(users);
    return memebers;
  }

  memebers = async (data) => {
    return new Promise(async (resolve) => {
      //map存了在不在状态 为什么不用一个对象 list还返回显示，map好做查找
      // 房间真实在线人
      let users = {};
      for (let index = 0; index < data.length; index++) {
        const item = data[index];
        if (index == 0) {
          users = await this.redisService.hget('room_' + item.roomId);
        }
        // console.log("##################用户:", item.userId);
        item.status = 0; // 不在线 1在线 2在这个房间
        if (users && users[item.userId] == 1) {
          // console.log("##################在房间:", item.userId);

          item.status = 2;
        } else if (users && users[item.userId] == 0) {
          // console.log("##################掉线:", item.userId);
          item.status = -1;
        }
        // if (
        //   global.$socketChat[item.userId] &&
        //   global.$socketChat[item.userId].userId == item.userId
        // ) {
        //   item.status = 1;
        //   // console.log("##################在线:", item.userId);
        //   if (users && users[item.userId] == 1) {
        //     // console.log("##################在房间:", item.userId);

        //     item.status = 2;
        //   } else if (users && users[item.userId] == 0) {
        //     // console.log("##################掉线:", item.userId);
        //     item.status = -1;
        //   }
        // }
      }
      resolve(data);
    });
  };

  async addRound(data) {
    // 每次要添加一笔游戏记录  且算出总分 ，当场对局 计分

    const finalScores: any = await this.repoChatRoundEntity
      .createQueryBuilder('round')
      .where('round.sceneId =:sceneId', { sceneId: data.sceneId })

      .orderBy('createdAt', 'DESC')
      .getOne();
    const roundInfo = data.round;
    let finalScoresObj :any ={};
   
    let rsData: any=[]
    if (finalScores) {
      finalScoresObj = JSON.parse(finalScores.scores);
      rsData =finalScoresObj.results
      console.log(finalScores.scores);
      if(finalScoresObj && rsData){
        for (let i = 0; i <roundInfo.users.length; i++) {
          let sd = roundInfo.users[i];
          let rs = rsData[i];
          if (!sd) continue;
          rs.ready = false;
          rs.score += sd.score;
          rs.numZiMo += sd.numZiMo;
          rs.numJiePao += sd.numJiePao;
          rs.numDianPao += sd.numDianPao;
          rs.numAnGang += sd.numAnGang;
          rs.numMingGang += sd.numWanGangs;
        }
      }
    }else{
      for (let i = 0; i <roundInfo.users.length; i++) {
        let sd = roundInfo.users[i];
        let rs :any={};
        if (!sd) continue;
        rs.ready = false;
        rs.score = sd.score;
        rs.numZiMo = sd.numZiMo;
        rs.numJiePao = sd.numJiePao;
        rs.numDianPao = sd.numDianPao;
        rs.numAnGang = sd.numAnGang;
        rs.numMingGang = sd.numWanGangs;
        rsData.push(rs)
      }
    }

    
    finalScoresObj =roundInfo;
    finalScoresObj.results =rsData;
    const round = await this.repoChatRoundEntity.save({...data,scores:JSON.stringify(finalScoresObj)});
    return round;
  }
  async getRound(scene) {
    // 每次要添加一笔游戏记录  且算出总分 ，当场对局 计分
    const round = await this.repoChatRoundEntity.findOne({where:{sceneId:scene}});
    return round;
  }
  
  async updateRoom(num,roomId){
    await this.repoRoom
    .createQueryBuilder()
    .update(ChatRoomEntity)
    .set({ nextButton: num })
    .where('roomId = :id', { id: roomId })
    .andWhere('isAdmin = :isAdmin', { isAdmin: 1})
    .execute()

    const dataView:any = await this.redisService.hget('createroom_' + roomId);
    if(dataView){
      dataView.nextButton=num;
      await this.redisService.hset({
        key: 'createroom_' + roomId,
        value: dataView,
        expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
      });
    }

  }
}
